<template>
  <div class="base-table">
    <!-- 表格 -->
    <el-table
      v-bind="tableProps"
      :data="data"
      :height="height"
      :max-height="maxHeight"
      :stripe="stripe"
      :border="border"
      :row-key="rowKey"
      :empty-text="computedEmptyText"
      :highlight-current-row="highlightCurrentRow"
      :show-header="showHeader"
      :row-class-name="rowClassName"
      :header-row-class-name="headerRowClassName"
      :header-cell-class-name="headerCellClassName"
      :cell-class-name="cellClassName"
      :row-style="rowStyle"
      :header-row-style="headerRowStyle"
      :header-cell-style="headerCellStyle"
      :cell-style="cellStyle"
      :default-sort="defaultSort"
      :default-expand-all="defaultExpandAll"
      :tree-props="treeProps"
      @row-click="handleRowClick"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
      v-loading="loading"
      element-loading-text="加载中..."
      element-loading-background="var(--theme-bg-color)"
    >
      <!-- 复选框列 -->
      <el-table-column v-if="selection" type="selection" width="55" align="center" fixed="left" />

      <!-- 序号列 -->
      <el-table-column
        v-if="index"
        type="index"
        label="序号"
        width="80"
        align="center"
        fixed="left"
      />

      <!-- 表格列 -->
      <template v-for="column in columns" :key="column.prop">
        <!-- 操作列 -->
        <el-table-column
          v-if="column.type === 'action'"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :align="column.align || 'center'"
        >
          <template #default="scope">
            <slot :name="column.slotName || 'action'" :row="scope.row" :$index="scope.$index">
              <div class="action-buttons">
                <el-button
                  v-for="(action, index) in column.actions"
                  :key="index"
                  :type="action.type || 'primary'"
                  :size="action.size || 'small'"
                  :icon="action.icon"
                  :disabled="
                    typeof action.disabled === 'function'
                      ? action.disabled(scope.row)
                      : action.disabled
                  "
                  :link="action.link"
                  @click.stop="action.handler && action.handler(scope.row, scope.$index)"
                >
                  {{ action.label }}
                </el-button>
              </div>
            </slot>
          </template>
        </el-table-column>

        <!-- 普通列 -->
        <el-table-column
          v-else
          :prop="column.prop"
          :label="column.label"
          :width="column.width"
          :min-width="column.minWidth"
          :fixed="column.fixed"
          :sortable="column.sortable"
          :sort-method="column.sortMethod"
          :sort-by="column.sortBy"
          :formatter="column.formatter"
          :align="column.align || 'left'"
          :show-overflow-tooltip="column.showOverflowTooltip !== false"
        >
          <!-- 自定义列 -->
          <template v-if="column.slotName" #default="scope">
            <slot :name="column.slotName" :row="scope.row" :$index="scope.$index">
              {{ column.prop ? scope.row[column.prop] : '' }}
            </slot>
          </template>
        </el-table-column>
      </template>

      <!-- 自定义列 -->
      <slot name="columns"></slot>
    </el-table>

    <!-- 分页 -->
    <div v-if="pagination" class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="pageSizes"
        :layout="paginationLayout"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        background
      />
    </div>
  </div>
</template>

<script setup lang="ts">
// import { ref, computed, watch } from 'vue';

interface TableColumn {
  prop?: string;
  label: string;
  width?: string | number;
  minWidth?: string | number;
  fixed?: boolean | 'left' | 'right';
  sortable?: boolean | 'custom';
  sortMethod?: (a: any, b: any) => number;
  sortBy?: string | ((row: any) => any);
  formatter?: (row: any, column: any, cellValue: any, index: number) => any;
  align?: 'left' | 'center' | 'right';
  showOverflowTooltip?: boolean;
  slotName?: string;
  type?: 'action';
  actions?: Array<{
    label: string;
    type?: 'primary' | 'success' | 'warning' | 'danger' | 'info';
    size?: 'large' | 'default' | 'small';
    icon?: string;
    disabled?: boolean | ((row: any) => boolean);
    link?: boolean;
    handler?: (row: any, index: number) => void;
  }>;
}

interface TreeProps {
  children?: string;
  hasChildren?: string;
  lazy?: boolean;
  load?: (row: any, treeNode: any, resolve: (data: any[]) => void) => void;
  indent?: number;
}

interface Props {
  data: any[];
  columns: TableColumn[];
  height?: string | number;
  maxHeight?: string | number;
  stripe?: boolean;
  border?: boolean;
  rowKey?: string;
  emptyText?: string;
  highlightCurrentRow?: boolean;
  showHeader?: boolean;
  rowClassName?: string | ((params: { row: any; rowIndex: number }) => string);
  headerRowClassName?: string | ((params: { row: any; rowIndex: number }) => string);
  headerCellClassName?:
    | string
    | ((params: { row: any; column: any; rowIndex: number; columnIndex: number }) => string);
  cellClassName?:
    | string
    | ((params: { row: any; column: any; rowIndex: number; columnIndex: number }) => string);
  rowStyle?: any | ((params: { row: any; rowIndex: number }) => any);
  headerRowStyle?: any | ((params: { row: any; rowIndex: number }) => any);
  headerCellStyle?:
    | any
    | ((params: { row: any; column: any; rowIndex: number; columnIndex: number }) => any);
  cellStyle?:
    | any
    | ((params: { row: any; column: any; rowIndex: number; columnIndex: number }) => any);
  defaultSort?: { prop: string; order: 'ascending' | 'descending' };
  defaultExpandAll?: boolean;
  treeProps?: TreeProps;
  selection?: boolean;
  index?: boolean;
  pagination?: boolean;
  pageSize?: number;
  currentPage?: number;
  total?: number;
  pageSizes?: number[];
  paginationLayout?: string;
  loading?: boolean;
  tableProps?: Record<string, any>;
}

const props = withDefaults(defineProps<Props>(), {
  data: () => [],
  columns: () => [],
  height: 'auto',
  maxHeight: undefined,
  stripe: true,
  border: false,
  rowKey: 'id',
  emptyText: '暂无数据',
  highlightCurrentRow: false,
  showHeader: true,
  selection: false,
  index: true,
  pagination: true,
  pageSize: 10,
  currentPage: 1,
  total: 0,
  pageSizes: () => [10, 20, 50, 100],
  paginationLayout: 'total, sizes, prev, pager, next, jumper',
  loading: false,
  tableProps: () => ({}),
  headerRowClassName: 'theme-header-row',
  rowClassName: 'theme-table-tr'
});

const emit = defineEmits<{
  (e: 'row-click', row: any, column: any, event: Event): void;
  (e: 'selection-change', selection: any[]): void;
  (e: 'sort-change', params: { column: any; prop: string; order: string }): void;
  (e: 'update:currentPage', page: number): void;
  (e: 'update:pageSize', size: number): void;
  (e: 'page-change', params: { page: number; size: number }): void;
}>();

// 计算空数据文本：加载中时不显示，只有在非加载状态且无数据时才显示
const computedEmptyText = computed(() => {
  return props.loading ? '' : props.emptyText;
});

// 分页相关
const currentPage = ref(props.currentPage);
const pageSize = ref(props.pageSize);

// 监听分页变化
watch(
  () => props.currentPage,
  val => {
    currentPage.value = val;
  }
);

watch(
  () => props.pageSize,
  val => {
    pageSize.value = val;
  }
);

// 处理页码变化
const handleCurrentChange = (page: number) => {
  emit('update:currentPage', page);
  emit('page-change', { page, size: pageSize.value });
};

// 处理每页条数变化
const handleSizeChange = (size: number) => {
  emit('update:pageSize', size);
  emit('page-change', { page: currentPage.value, size });
};

// 处理行点击事件
const handleRowClick = (row: any, column: any, event: Event) => {
  emit('row-click', row, column, event);
};

// 处理选择变化事件
const handleSelectionChange = (selection: any[]) => {
  emit('selection-change', selection);
};

// 处理排序变化事件
const handleSortChange = (params: { column: any; prop: string; order: string }) => {
  emit('sort-change', params);
};
</script>

<style lang="scss" scoped>
.base-table {
  width: 100%;

  .action-buttons {
    display: flex;
    justify-content: center;
    gap: 8px;
  }

  .pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
    background-color: var(--theme-module-bg);
    color: var(--theme-text-color);
  }
  :deep(.theme-header-row th) {
    background-color: var(--theme-table-header-bg-color);
  }
  :deep(.el-table tr.theme-table-tr),
  :deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
    background-color: var(--theme-table-tr-color);
    color: var(--theme-text-color);
  }

  // 修复悬停样式，确保对所有行都生效
  :deep(.el-table__body tr.hover-row td.el-table__cell),
  :deep(.el-table__body tr.theme-table-tr.hover-row td.el-table__cell),
  :deep(.el-table--striped .el-table__body tr.el-table__row--striped.hover-row td.el-table__cell) {
    background-color: var(--theme-table-tr-hover-color) !important;
  }

  :deep(.el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf) {
    border-bottom: 1px solid var(--theme-border-color);
  }

  // 控制 loading 文字颜色
  :deep(.el-loading-text) {
    color: var(--theme-text-color);
  }

  // 确保表格背景色与主题一致
  :deep(.el-table) {
    background-color: var(--theme-module-bg);
    color: var(--theme-text-color);
    min-height: 400px; // 设置最小高度，确保无数据时也有合适的显示高度
  }

  :deep(.el-table__inner-wrapper) {
    background-color: var(--theme-module-bg);
  }

  :deep(.el-table__body-wrapper) {
    background-color: var(--theme-module-bg);
  }

  :deep(.el-table__empty-block) {
    background-color: var(--theme-module-bg);
  }

  :deep(.el-table__empty-text) {
    color: var(--theme-text-color);
  }
}
</style>
